#ifndef Math_H
#define Math_H

#include <array>
#include <vector>




//template<class Type, int numberRowIn, int numberColIn>
//class Matrix
//{
//
//public:
//
//    Matrix();
//
//    ~Matrix();
//
//    int size() const
//    {
//        return numberEle;
//    }
//
//
//    void setZero()
//    {
//        for (int i = 0; i < numberRow; i++)
//        {
//            for (int j = 0; j < numberRow; j++)
//            {
//                data[i][j] = 0.0;
//            }
//        }
//    }
//
//    //void setData(Type* dataIn);
//
//
//
//
//    inline Type& operator () (int i, int j)
//    {
//        return data[i][j];
//    };
//
//    inline Type operator () (int i, int j) const
//    {
//        return data[i][j];
//    };
//
//    inline Type& operator () (int i)
//    {
//        return data[i][0];
//    };
//
//    inline Type operator () (int i) const
//    {
//        return data[i][0];
//    };
//
//    void operator=(const Matrix<Type, numberRowIn, numberColIn>& matrix)
//    {
//
//    }
//
//    Type data[numberRowIn][numberColIn];
//
//    int numberRow = numberRowIn;
//    int numberCol = numberColIn;
//    //number of element
//    int numberEle = numberRowIn * numberColIn;
//    
//
//private:
//
//};



template<typename Type, int NumberRow, int NumberCol>
class Matrix
{

public:

    Matrix() {};

    ~Matrix() {};

    int size() const
    {
        //return numberEle;
        return NumberRow * NumberCol;
    }


    void setZero()
    {
        for (int i = 0; i < NumberRow * NumberCol; i++)
        {
            buf[i] = 0.0;
        }
    }

    //void setData(Type* dataIn);


    inline Type& operator () (int i, int j)
    {
        return buf[i * NumberCol + j];
    };

    inline Type operator () (int i, int j) const
    {
        return buf[i * NumberCol + j];
    };

    inline Type& operator () (int i)
    {
        return buf[i];
    };

    inline Type operator () (int i) const
    {
        return buf[i];
    };

    void operator=(const Matrix<Type, NumberRow, NumberCol>& matrix)
    {
        for (int i = 0; i < NumberRow * NumberCol; i++)
        {
            buf[i] = matrix(i);
        }
    }

    std::array<Type, NumberRow* NumberCol> buf;

    //int numberRow = numberRowIn;
    //int numberCol = numberColIn;
    //number of element
    //int numberEle = numberRowIn * numberColIn;


private:

};


typedef Matrix<double, 2, 2> Matrix2d;
typedef Matrix<double, 3, 3> Matrix3d;
typedef Matrix<double, 4, 4> Matrix4d;

typedef Matrix<double, 2, 1> Vector2d;
typedef Matrix<double, 3, 1> Vector3d;

typedef Matrix<int, 3, 1> Vector3i;

#endif
